#ifndef LOG_FILE_H_
#define LOG_FILE_H_

#include <cstdio>
#include <ctime>
#include <memory>
#include <string>

#include "netlib/base/mutex.h"
#include "netlib/base/noncopyable.h"

namespace netlib {

class FileHelper {
public:
	explicit FileHelper(const char* filename);
	explicit FileHelper(std::string&& filename) : FileHelper(filename.c_str()) {}
	~FileHelper();

	void Flush();
	void Append(const char* data, size_t len);
	size_t WrittenSize() const { return written_size_; }

private:
	size_t Write(const char* data, size_t len) { return fwrite(data, 1, len, file_); }

	FILE* file_;
	size_t written_size_{0};
};

class LogFile : NonCopyable {
public:
	static const time_t kRollTime = 24 * 60 * 60;
	static const off_t kDefaultMaxBytes = 1024 * 1024 * 1024;

	LogFile(const std::string& basename,
	        std::string dirname,
	        int check_lines = 2,
	        time_t interval = 3,
	        off_t max_bytes = kDefaultMaxBytes,
	        bool is_thread_safe = true);
	~LogFile() = default;

	void RollFile();
	void Append(const char* data, size_t len);
	void Flush();

private:
	void CheckDirectory();
	void CheckAndRoll();
	std::string GetFileName();
	void AppendWithOutLock(const char* data, size_t len);

	const off_t kMaxBytes{kDefaultMaxBytes};
	const time_t kFlushInterval{3};
	const int kCheckLines{100};

	int count_{0};
	std::string basename_;
	std::string dirname_;
	time_t start_time_;
	time_t last_flush_;
	std::unique_ptr<FileHelper> file_;
	std::unique_ptr<MutexLock> mutex_;
};

} // namespace netlib

#endif // LOG_FILE_H_